/*	HTML5AS3MultiUp v0.1 <http://code.google.com/p/html5-as3-multiupload/> 
	is released under the MIT License <http://www.opensource.org/licenses/mit-license.php> 
*/

package flasheep.proj.multiup.as3.utils 
{
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.events.SecurityErrorEvent;
	import flash.system.Security;
	import flasheep.ascaffold.events.DataEvent;
	import flasheep.ascaffold.utils.external.JSInterface;
	import flasheep.ascaffold.utils.fileupload.FileRefProxy;
	import com.adobe.serialization.json.JSON;
	import flasheep.ascaffold.utils.fileupload.FileRefTool;
	
	/**
	 * ...
	 * @author Luan(tonylua@sina.com)
	 */
	public class ListHelper extends EventDispatcher
	{
		private var _source:Array = [];
		private var _serverRtnCache:Array = [];
		private var _uploadingFlag:int = -1;
		private var _setting:Object;
		
		public function ListHelper(setting:Object) 
		{			
			_setting = setting;
			
			Security.allowDomain("*");
			JSInterface.regist('cancelItem', _onItemCancel);
			JSInterface.regist('clickSubmit', _onSubmitClick);
			JSInterface.regist('toggleButton', _onToggleButton);
			JSInterface.regist('reactive', _onReactive);
		}
		
		/**
		 * 填充列表
		 * @param	source	FileRefProxy[]
		 */
		public function fillList(source:Array):void
		{
			_source = source;			
			_sliceSourceLength();
			
			_order();
			
			JSInterface.call(_setting.callback_listchange, FileRefTool.ASArr2JSArr(_source));
		}
		
		/**
		 * 扩展列表
		 * @param	conArr
		 */
		public function concatList(conArr:Array):void
		{
			//是否重复
			var sameArr:Array = [];
			loop1: for (var ii:uint = 0; ii < conArr.length; ii++)
			{
				var newFile:FileRefProxy = conArr[ii] as FileRefProxy;
				
				loop2: for (var jj:uint = 0; jj < _source.length; jj++)
				{
					var oldFile:FileRefProxy = _source[jj] as FileRefProxy;
					
					if (newFile.name == oldFile.name 
						&& newFile.size == oldFile.size)
					{
						sameArr.push(ii);
						continue loop1;
					}
				}
			}
			sameArr.sort(Array.DESCENDING);
			sameArr.forEach(function(a:Object, b:uint, c:Array):void { 
				conArr.splice(a, 1);
			});
			
			//添加
			var max:uint = _setting.max_filecount,
				n:uint = conArr.length + _source.length > max
							? max - _source.length
							: conArr.length;
			
			_source = _source.concat(conArr);
			
			_sliceSourceLength();
			
			_order();
			
			JSInterface.call(_setting.callback_listchange, FileRefTool.ASArr2JSArr(_source));
		}
		
		//给文件对象赋予序号
		private function _order():void
		{
			var i:uint = 0, lng:uint = _source.length;
			
			for (; i < lng; i++)
				(_source[i] as FileRefProxy).__rptIndex = i+0;
		}
		
		//数量过滤
		private function _sliceSourceLength():void 
		{
			if ( _source.length > _setting.max_filecount )
			{
				_source = _source.slice(0, _setting.max_filecount );
			}
		}
		
		//队列依次上传
		private function _queueUpload():void
		{			
			var fileRef:FileRefProxy = _source[_uploadingFlag] as FileRefProxy;
			
			//JSInterface.call(_setting.callback_notice, FileRefTool.AS3FileToHTML5File(fileRef));
			//return;
			
			fileRef.addEventListener(ProgressEvent.PROGRESS, _onItemUploadEvents);
			fileRef.addEventListener(Event.COMPLETE, _onItemUploadEvents);
			fileRef.addEventListener(flash.events.DataEvent.UPLOAD_COMPLETE_DATA, _onItemUploadEvents);
			fileRef.addEventListener(IOErrorEvent.IO_ERROR, _onItemUploadEvents);
			fileRef.addEventListener(SecurityErrorEvent.SECURITY_ERROR, _onItemUploadEvents);
			fileRef.addEventListener('validationError', _onItemUploadEvents);
			
			//前端验证
			if ( !(new RegExp( _setting.re_file_names||'*.jpg;*.jpeg;*.gif;*.png', _setting.re_file_options||'' ).test(fileRef.name)) )
			{
				fileRef.dispatchEvent(new DataEvent('validationError', _setting.i18n_err_type));
			}
			else if ( fileRef.size > _setting.max_filesize )
			{
				fileRef.dispatchEvent(new DataEvent('validationError', 
					_setting.i18n_err_size_pre+ _setting.max_filesize/1024 + 'kb'));
			}
			else
			{
				fileRef.upload();
			}
		}
		
		private function _onItemUploadEvents(e:Event):void 
		{
			var obj:FileRefProxy = e.target as FileRefProxy;
			var jsFile:Object = FileRefTool.AS3FileToHTML5File(obj);
			var idx:uint = obj.__rptIndex;
			
			var rtn:Object = {id:-1}; 
			
			switch(e.type)
			{
				case ProgressEvent.PROGRESS:
					JSInterface.call(_setting.callback_progress, jsFile, e['bytesLoaded'] / e['bytesTotal'], idx);
				break;
				
				case IOErrorEvent.IO_ERROR:
					JSInterface.call(_setting.callback_progress, jsFile, 0, idx);
					JSInterface.call(_setting.callback_error, jsFile, _setting.i18n_up_ioerror, idx); //'传输失败'
					
					_serverRtnCache.push(rtn);
					
					_next();
				break;
				
				case SecurityErrorEvent.SECURITY_ERROR:
					JSInterface.call(_setting.callback_progress, jsFile, 0, idx);
					
					_serverRtnCache.push(rtn);
					
					_next();
				break;
				
				case 'validationError':
					JSInterface.call(_setting.callback_progress, jsFile, 0, idx);
					JSInterface.call(_setting.callback_error, jsFile, (e as DataEvent).data as String, idx); 
					
					_serverRtnCache.push(rtn);
					
					_next();
				break;
				
				case Event.COMPLETE:
					JSInterface.call(_setting.callback_progress, jsFile, 1, idx);
				break;
				
				case flash.events.DataEvent.UPLOAD_COMPLETE_DATA:
					JSInterface.call(_setting.callback_progress, jsFile, 1, idx);
					
					var str:String = (e as flash.events.DataEvent).data;
					
					try
					{
						rtn = (com.adobe.serialization.json.JSON).decode(str);
						if (rtn.resultCode*1 == 0)	//成功
						{
							JSInterface.call(_setting.callback_success, jsFile, _setting.i18n_up_upload_ok, idx); 
						}
						else
						{
							JSInterface.call(_setting.callback_error, jsFile, rtn.describe, idx);
						}
					}catch (ex:Error){}
					
					_serverRtnCache.push(rtn);	//记录返回值, 队列完成时交给js
					
					_next();
				break;
			}
		}
		
		private function _next():void 
		{
			if (++_uploadingFlag <= _source.length - 1)
			{
				//单个完成
				_queueUpload();
			}
			else
			{
				//队列完成
				_uploadingFlag = -1;
				
				if (_setting.callback_queueloaded) {
					var jsParam1:String = _serverRtnCache.map(function(a:Object, b:uint, c:Array):String {
						return a.id;
					}).join(',');
					
					JSInterface.call(_setting.callback_queueloaded, jsParam1);
				}
				
				if ( _setting.callback_reactive ) {
					JSInterface.call(_setting.callback_reactive);
				}
			}
		}
		
		
		/**********************************JS回调************************************/
		
		//点击取消
		private function _onItemCancel(idx:uint):void 
		{
			if (_uploadingFlag != -1) return;
			
			_source.splice(idx, 1);
			
			_order();
			
			JSInterface.call(_setting.callback_listchange, FileRefTool.ASArr2JSArr(_source));
		}
		
		//回到初始态
		private function _onReactive():void 
		{
			_uploadingFlag = -1;
			_serverRtnCache = [];
			_source = [];
		}
		
		//切换按钮
		private function _onToggleButton(type:String):void 
		{
			this.dispatchEvent(new DataEvent('toggleButton', type));
		}
		
		//点击了上传图片
		private function _onSubmitClick():void 
		{
			if (!_source.length) {
				return;
			}
			
			_uploadingFlag = 0;
			_serverRtnCache = [];
			
			JSInterface.call(_setting.callback_uploadstart, FileRefTool.ASArr2JSArr(_source));
			
			_queueUpload();
		}
		
		
	}
}